package org.hao.samples.util;


import java.util.Arrays;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class LogAspect {
	
	@Pointcut("execution(* org.hao.samples.controller.*.*save*(..))")
	public void allMethod() {

	}

	@After("allMethod()")
	public void afterLog(JoinPoint point) {
		System.out.println("afterLog---------最终通知");
		System.out.println("afterLog---------目标方法为：" + point.getSignature().getDeclaringTypeName() + "."
				+ point.getSignature().getName());
		System.out.println("afterLog---------参数为：" + Arrays.toString(point.getArgs()));
		System.out.println("afterLog---------被织入的目标对象为：" + point.getTarget());
	}

	@AfterReturning(value = "allMethod()", returning = "returnValue")
	public void afterReturningLog(JoinPoint point, Object returnValue) {
		System.out.println("afterReturningLog------返回值后通知");
		System.out.println("afterReturningLog------目标方法为：" + point.getSignature().getDeclaringTypeName() + "."
				+ point.getSignature().getName());
		System.out.println("afterReturningLog------" + Arrays.toString(point.getArgs()));
		System.out.println("afterReturningLog------" + returnValue);
	}

	@AfterThrowing(throwing = "ex", value = "allMethod()")
	public void afterThrowingLog(Throwable ex) {
		System.out.println("afterThrowingLog-------进入异常通知");
		System.out.println("afterThrowingLog-------异常信息：" + ex.getMessage());
	}

	@Around("allMethod()")
	public Object doAround(ProceedingJoinPoint p) throws Throwable {
		System.out.println("--------------Around--------------进入环绕通知");
		  long startTime = System.currentTimeMillis();  
		Object obj = p.proceed();
		  long endTime = System.currentTimeMillis();  
		  MethodSignature signature = (MethodSignature) p.getSignature();  
	        String methodName = signature.getDeclaringTypeName() + "." + signature.getName(); 
	        
		  System.out.println("目标方法："+methodName);
		  System.out.println("运行耗时："+(endTime-startTime)+"ms");
		System.out.println("--------------Around--------------结束方法调用");
		return obj;

	}
}
